package main

import (
	"encoding/json"
	"fmt"
)

/*
1、结构体的所有字段在内存中是连续的
2、结构体是用户单独定义的类型，和其它类型进行转换时需要有完全相同的字段（名字、个数和类型）
3、结构体进行type重新定义（相当于取别名），go认为是新的数据类型，但是相互之间可以强转
type Student struct{
	Name string
}
type Stu Student
4、struct的每个字段上，可以写上一个tag，该tag可以通过反射机制获取，常见的使用场景就是序列化和反序列化

*/
type Point struct {
	x int
	y int
}
type Rect struct {
	leftUp, rightDown Point
}
type Rect2 struct {
	leftUp, rightDown *Point
}

//2
type A struct {
	Num int
}
type B struct {
	Num int
}

//4
type Monster struct {
	Name  string `json:"name"` //`json:"name"`就是struct tag
	Age   int    `json:"age"`
	Skill string `json:"skill"`
}

func main() {
	r1 := Rect{Point{1, 2}, Point{3, 4}}
	//r1有四个int，在内存中是连续分布的
	fmt.Printf("r1.leftUp.x 地址=%p r1.leftUp.y 地址=%p r1.rightDown.x 地址=%p r1.rightDown.y 地址=%p\n",
		&r1.leftUp.x, &r1.leftUp.y, &r1.rightDown.x, &r1.rightDown.y)
	r2 := Rect2{&Point{1, 2}, &Point{3, 4}}
	fmt.Printf("r2.leftUp 本身的地址=%p r2.rightDown 本身的地址=%p\n",
		&r2.leftUp, &r2.rightDown)
	//他们指向的地址不一定连续...,这个要看系统在运行时是如何分配的
	fmt.Printf("r2.leftUp 指向地址=%p r2.rightDown 指向地址=%p\n",
		r2.leftUp, r2.rightDown)

	//2
	var a A
	var b B
	a = A(b)
	fmt.Println(a, b)

	//4
	//创建一个Monster变量
	monster := Monster{"牛魔王", 500, "芭蕉扇"}
	//将monster变量序列化为json格式字符串
	//json.Marshal函数使用反射，这个讲解反射时，会详细介绍
	jsonStr, err := json.Marshal(monster)
	if err != nil {
		fmt.Println("json 处理错误", err)
	}
	fmt.Println("jsonStr", string(jsonStr))
}
